<template>
  <div class="app-container">
    <!--条件搜索表单-->
    <el-row>
      <el-form :inline="true">
        <el-form-item>
          <el-input v-model="searchObj.name" placeholder="部门名称" />
        </el-form-item>
        <el-form-item>
          <el-input v-model="searchObj.phone" placeholder="部门电话" />
        </el-form-item>
        <el-form-item>
          <el-input v-model="searchObj.email" placeholder="部门邮箱" />
        </el-form-item>
        <el-form-item>
          <el-select v-model="searchObj.status" placeholder="状态" clearable @change="getAll()">
            <el-option v-for="item in statusOptions" :key="item.value" :value="item.value" :label="item.text" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" @click="getAll()">查询</el-button>
          <el-button icon="el-icon-refresh" @click="reset()">清空</el-button>
        </el-form-item>
      </el-form>
    </el-row>

    <!-- 工具栏 -->
    <el-row>
      <el-button v-if="hasPerm('sys:dept:save')" type="primary" icon="el-icon-plus" @click="openEdit(null, true)">新增</el-button>
      <el-button type="primary" icon="el-icon-arrow-down" @click="expandAll(true)">全部展开</el-button>
      <el-button type="primary" icon="el-icon-arrow-up" @click="expandAll(false)">全部折叠</el-button>
    </el-row>

    <!-- banner列表 :data="list"表示遍历list数组 stripe条纹 -->
    <el-table
      ref="deptTableRef"
      v-loading="loading"
      element-loading-text="正在努力加载数据中..."
      :data="list"
      :border="false"
      stripe
      row-key="id"
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
      :expand-row-keys="expandedKeys"
      style="margin: 15px 0px"
    >
      <el-table-column prop="name" fixed="left" label="部门名称" min-width="200" show-overflow-tooltip />
      <el-table-column prop="phone" label="部门电话" show-overflow-tooltip />
      <el-table-column prop="email" label="部门邮箱" show-overflow-tooltip />
      <el-table-column prop="leaderName" label="负责人" show-overflow-tooltip />
      <el-table-column prop="priority" label="优先级" min-width="100" sortable />
      <el-table-column prop="status" label="状态" min-width="100" sortable :filters="statusOptions" :filter-method="filterHandler">
        <template slot-scope="scope">
          <div v-if="!hasPerm('sys:dept:update-status')">
            <el-tag v-if="scope.row.status === 0" type="primary">正常</el-tag>
            <el-tag v-if="scope.row.status === 1" type="danger">停用</el-tag>
          </div>
          <el-switch
            v-if="hasPerm('sys:dept:update-status')"
            v-model="scope.row.status"
            :active-value="0"
            :inactive-value="1"
            @change="handleStatusChange(scope.row)"
          />
        </template>
      </el-table-column>
      <el-table-column prop="remark" label="备注" show-overflow-tooltip />
      <el-table-column prop="createTime" label="创建时间" min-width="100" sortable show-overflow-tooltip />

      <!-- 操作 -->
      <el-table-column v-if="hasPerm('sys:dept:save', 'sys:dept:update', 'sys:dept:delete')" label="操作" fixed="right" width="200" align="center">
        <template slot-scope="scope">
          <el-link v-if="hasPerm('sys:dept:save')" type="primary" icon="el-icon-plus" @click="openEdit(scope.row, true)">添加</el-link>
          <el-divider v-if="hasPerm('sys:dept:update')" direction="vertical" />
          <el-link v-if="hasPerm('sys:dept:update')" type="success" icon="el-icon-edit" @click="openEdit(scope.row, false)">修改</el-link>
          <el-divider v-if="hasPerm('sys:dept:delete')" direction="vertical" />
          <el-link v-if="hasPerm('sys:dept:delete')" type="danger" icon="el-icon-remove" @click="remove(scope.row)">删除</el-link>
        </template>
      </el-table-column>
    </el-table>

    <!-- 表单 -->
    <el-dialog v-if="hasPerm('sys:dept:save', 'sys:dept:update')" :title="dialogTitle" :visible.sync="visible" @close="close('deptForm')">
      <el-form ref="deptForm" :model="dept" :rules="rules" label-width="100px">
        <el-row :gutter="10">
          <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8">
            <el-form-item label="ID" prop="id" :hidden="true">
              <el-input v-model="dept.id" disabled />
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8">
            <el-form-item label="所属上级" prop="parentId">
              <el-cascader
                ref="parentCascader"
                v-model="dept.parentId"
                :options="list"
                :props="{ value: 'id', label: 'name', checkStrictly: true }"
                clearable
                filterable
                placeholder="请选择上级"
                style="width: 100%"
              >
                <template slot-scope="{ node, data }">
                  <span>{{ data.name }}</span>
                  <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
                </template>
              </el-cascader>
            </el-form-item>
          </el-col>

          <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8">
            <el-form-item label="部门名称" prop="name" required>
              <el-input v-model="dept.name" placeholder="请输入部门名称" />
            </el-form-item>
          </el-col>

          <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8">
            <el-form-item label="部门电话" prop="phone" required>
              <el-input v-model="dept.phone" placeholder="请输入部门电话" />
            </el-form-item>
          </el-col>

          <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8">
            <el-form-item label="部门邮箱" prop="email" required>
              <el-input v-model="dept.email" placeholder="请输入部门邮箱" />
            </el-form-item>
          </el-col>

          <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8">
            <el-form-item label="部门负责人" prop="leaderId" :hidden="true">
              <el-input v-model="dept.leaderId" placeholder="请输入部门负责人" />
            </el-form-item>
          </el-col>

          <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8">
            <el-form-item label="部门负责人" prop="leaderName" required>
              <el-input v-model="dept.leaderName" placeholder="请输入部门负责人">
                <template #append>
                  <el-button icon="el-icon-search" @click="leaderVisible = true" />
                </template>
              </el-input>
            </el-form-item>
          </el-col>

          <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8">
            <el-form-item label="状态" prop="status">
              <el-select v-model="dept.status" style="width: 100%" placeholder="请选择状态">
                <el-option v-for="item in statusOptions" :key="item.value" :label="item.text" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>

          <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="8">
            <el-form-item label="优先级" prop="priority">
              <el-input-number v-model="dept.priority" controls-position="right" placeholder="请输入优先级" style="width: 100%" />
            </el-form-item>
          </el-col>

          <el-col>
            <el-form-item label="部门备注" prop="remark">
              <el-input v-model="dept.remark" :rows="3" type="textarea" placeholder="请输入备注" maxlength="255" show-word-limit />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer">
        <el-button @click="close('deptForm')">取 消</el-button>
        <el-button type="primary" @click="save('deptForm')">确 定</el-button>
      </div>
    </el-dialog>

    <UserSelect :visible.sync="leaderVisible" :user-id="dept.leaderId" @getSelectUser="getSelectUser" />
  </div>
</template>

<script>
// 引入api接口定义的js文件
import deptApi from '@/api/sys/dept'
import UserSelect from '@/components/UserDialog/index'

export default {
  components: {
    UserSelect
  },
  data() {
    // 定义变量和初始值
    return {
      statusOptions: [
        { value: 0, text: '正常' },
        { value: 1, text: '停用' }
      ],

      // 列表相关
      loading: false,
      searchObj: {}, // 条件封装对象
      list: [], // 列表
      ids: [], // ID集合
      expandedKeys: [], // 默认展开部门列表

      leaderVisible: false,

      // 表单相关
      dialogTitle: '',
      visible: false,
      dept: {
        parentId: undefined,
        name: '',
        phone: '',
        email: '',
        leaderId: 1,
        status: 0,
        priority: 0,
        remark: '',
        leaderName: ''
      },

      // 验证规则
      rules: {
        name: [{ required: true, message: '部门名称不能为空', trigger: 'blur' }],
        phone: [
          { required: true, message: '部门电话不能为空', trigger: 'blur' },
          {
            pattern: /^1[3456789]\d{9}$/,
            message: '电话格式错误',
            trigger: 'blur'
          }
        ],
        email: [
          { required: true, message: '部门邮箱不能为空', trigger: 'blur' },
          { type: 'email', message: '邮箱格式错误', trigger: 'blur' }
        ]
      }
    }
  },

  // 创建函数
  created() {
    this.getAll()
  },

  // 方法
  methods: {
    // 加载列表数据
    getAll() {
      this.loading = true
      deptApi
        .getList(this.searchObj)
        .then((response) => {
          this.list = response.data
        })
        .finally(() => {
          this.loading = false
        })
    },

    // 行内筛选处理
    filterHandler(value, row, column) {
      const property = column['property']
      return row[property] === value
    },

    remove(row) {
      this.$confirm('此操作将永久删除部门信息, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        deptApi.deleteById(row.id).then((resp) => {
          this.$message.success('删除成功!')
          this.getAll()
        })
      })
    },

    // 复选框选中
    handleSelectionChange(r) {
      // 得到选中的id
      this.ids = r.map((v) => v.id)
    },

    // 改变状态
    handleStatusChange(row) {
      const text = row.status === 0 ? '正常' : '停用'
      this.$confirm(`此操作将修改 '${row.name}' 状态为 '${text}', 是否继续?`, '部门状态修改', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          deptApi
            .updateStatus(row.id, row.status)
            .then((resp) => {
              this.$message.success('操作成功！')
            })
            .catch(() => {
              row.status = row.status === 0 ? 1 : 0
            })
        })
        .catch(() => {
          row.status = row.status === 0 ? 1 : 0
        })
    },

    setAllExpand(arr, state) {
      arr.forEach((i) => {
        // toggleRowExpansion(i, isExpand)用于多选表格，切换某一行的选中状态
        // 如果使用了第二个参数，则是设置这一行选中与否（selected 为 true 则选中）
        this.$refs.deptTableRef.toggleRowExpansion(i, state)
        if (i.children) {
          this.setAllExpand(i.children, state)
        }
      })
    },

    // 全部展开/折叠
    expandAll(expand) {
      this.$nextTick(() => {
        this.setAllExpand(this.list, expand)
      })
    },

    // 获取选择的用户信息
    getSelectUser(row) {
      console.log('select user', row)
      this.dept.leaderName = row.nickname
      this.dept.leaderId = row.id
    },

    // 新增
    openEdit(row, isEdit) {
      this.visible = true
      if (isEdit) {
        // 新增
        this.dialogTitle = '新增部门'
        this.dept.parentId = row ? row.id : 0
        this.dept.priority = this.list.length + 2
      } else {
        // 编辑
        this.dialogTitle = '编辑部门'

        deptApi.getById(row.id).then((res) => {
          Object.assign(this.dept, res.data)
        })
      }
    },

    // 关闭
    close(form) {
      this.visible = false
      this.$refs[form].resetFields()
    },

    // 保存
    save(form) {
      this.$refs[form].validate((valid) => {
        if (valid) {
          this.dept.parentId = this.$refs['parentCascader'].getCheckedNodes()[0]?.value ?? 0
          const apiCall = this.dept.id ? deptApi.update(this.dept) : deptApi.save(this.dept)
          apiCall.then(() => {
            this.$message.success('保存成功!')
            this.getAll()
            this.close(form)
          })
        }
      })
    },

    // 批量删除
    batchDelete() {
      if (this.ids.length > 0) {
        this.$confirm('此操作将永久删除部门信息,是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
          // 确定执行then方法
          .then(() => {
            deptApi.batchDelete(this.ids).then((resp) => {
              this.$message.success('删除成功!')
              this.getAll()
            })
          })
      } else {
        this.$message.warning('至少选择一条数据!')
      }
    },

    // 重置
    reset() {
      this.searchObj = {}
      this.getAll()
    }
  }
}
</script>

<style></style>
